import Vuex from "vuex";

export const vuexStore = new Vuex.Store({
	state: {} as { [key: string]: any },
	mutations: {},
	actions: {},
	getters: {},
	modules: {},
});

//更新store状态
interface Module {
	namespaced: boolean;
	state: {};
	mutations: {};
}

class StoreManager {
	register(moduleName: string): Store {
		return new Store(moduleName);
	}
}
export class Store {
	private moduleName: string;
	private module: Module = {
		namespaced: true,
		state: {} as { [key: string]: any },
		mutations: {},
	};
	constructor(moduleName: string) {
		this.moduleName = moduleName;
		//注册moduleName的子模块
		if (!vuexStore.hasModule(this.moduleName)) {
			vuexStore.registerModule(this.moduleName, this.module);
		} else {
			this.module.state = vuexStore.state[this.moduleName];
		}
	}
	/** 获取存储到vuex的数据 */
	get<T = Record<string, any>>(key: string, errorResult = {}): T {
		if (!key) {
			return {} as T;
		}
		let result = vuexStore.state[this.moduleName][key];
		if (result) {
			return result as T;
		}

		result = sessionStorage.getItem(`${this.moduleName}/${key}`);
		return (result ? JSON.parse(result) : errorResult) as T;
	}
	/** 存储到vuex的数据 */
	set<T = Record<string, any>>(key: string, value: T, saveLocal: boolean = true): void {
		if (saveLocal) {
			//如果需要存储到本地，使用sessionStorage进行存储
			sessionStorage.setItem(`${this.moduleName}/${key}`, JSON.stringify(value));
		}
		// 更新store下的子模块的state
		(<any>this.module.state)[key] = value;
		this.updateModule();
	}
	/** 删除模块下对应key的值 */
	delete(key: string): void {
		if (key in this.module.state) {
			(<any>this.module.state)[key] = {};
			this.updateModule();
		}
		sessionStorage.removeItem(`${this.moduleName}/${key}`);
	}
	/** 清空模块下所有key的值 */
	async clear() {
		const localKeys = await this.getLocalKeys();
		const keys = Object.keys(vuexStore.state[this.moduleName]);
		keys.forEach(e => {
			(<any>this.module.state)[e] = {};
		});
		this.updateModule();
		localKeys.forEach(e => {
			sessionStorage.removeItem(<string>e);
		});
	}
	/** 检测当前模块下是否已存在该key */
	checkStoreKeys(key: string): boolean {
		return Object.keys(vuexStore.state[this.moduleName]).includes(key);
	}
	/** 根据key响应式对象 */
	getReactObj(key: string): any {
		return vuexStore.state[this.moduleName][key];
	}
	/** 获取本地存储在该模块的key */
	getLocalKeys(): Promise<Array<string | unknown>> {
		const _this = this;
		return new Promise(resolve => {
			if (Object.keys(sessionStorage).length > 0) {
				const localKeys = Object.keys(sessionStorage).filter(key => {
					return key.split("/")[0] == _this.moduleName;
				});
				resolve(localKeys);
			} else {
				resolve([]);
			}
		});
	}
	updateModule() {
		// 更换更新后的子模块
		if (vuexStore.hasModule(this.moduleName)) {
			vuexStore.unregisterModule(this.moduleName);
		}
		vuexStore.registerModule(this.moduleName, this.module);
	}
}
export const storeManager = new StoreManager();
